package com.clhbolg.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileNameUtil;
import com.clhbolg.domain.vo.ArticleVo;
import com.clhbolg.domain.vo.CategoryVo;
import com.clhbolg.domain.vo.TagVo;
import com.clhbolg.enums.FilePathEnum;
import com.clhbolg.mapper.es.ArticlesSearchMapper;
import com.clhbolg.model.dto.*;
import com.clhbolg.model.vo.request.*;
import com.clhbolg.service.*;
import com.clhbolg.strategy.context.UploadStrategyContext;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;

/**
 * 后台管理员接口
 *
 * @Author cailinhu
 * @Description TODO
 * @Date 2023/2/7 15:48
 * @Version 1.0
 */
@RestController
@RequestMapping("/admin")
//@SaCheckRole(value = {"admin","viewadmin"},mode = SaMode.OR)
public class AdminController extends BaseController {

    @Autowired
    ICategoryService categoryService;

    @Autowired
    ITagService tagService;

    @Autowired
    IArticleService articleService;

    @Autowired
    IResourceService resourceService;
    @Autowired
    IUserAuthService userAuthService;

    @Autowired
    IUserRoleService userRoleService;
    @Autowired
    ITalkService talkService;
    @Autowired
    WebInfoService webInfoService;

    @Autowired
    IWebsiteConfigService websiteConfigService;
    @Autowired
    private UploadStrategyContext uploadStrategyContext;

    @Autowired
    private ArticlesSearchMapper articlesSearchMapper;

    @Autowired
    private ICommentService commentService;

    @Autowired
    IPhotoService photoService;
    @Autowired
    IPhotoAlbumService photoAlbumService;

    /**
     * 上传图片
     * @param file
     * @return
     */
    @PostMapping("/articles/images")
    @SaCheckRole("admin")
    public R uploadImage(MultipartFile file){
        String fileUrl = uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.ARTICLE.getPath());
        return R.ok(R.message,fileUrl);
    }

    /**
     * 删除图片
     * @param fileName
     * @return
     */
    @PostMapping("/articles/delImages")
    @SaCheckRole("admin")
    public R deleteImage(@RequestParam String fileName){
        String name = FileNameUtil.getName(fileName);
        uploadStrategyContext.executeDeleteStrategy(FilePathEnum.ARTICLE.getPath()+name);
        return R.ok();
    }
    //categories/search

    /**
     * 查询所有分类
     * @param keywords
     * @return
     */
    @GetMapping("/categories/search")
    public R getCategories(@RequestParam(required = false) String keywords){
        List<CategoryVo> categoryVos = categoryService.queryList(keywords);
        return R.ok(categoryVos);
    }

    /**
     * 查询所有标签
     * @param keywords
     * @return
     */
    @GetMapping("/tags/search")
    public R getTags(@RequestParam(required = false) String keywords){
        List<TagVo> tagVos = tagService.queryList(keywords);
        return R.ok(tagVos);
    }

    /**
     * 添加新文章
     * @param vo
     * @return
     */
    @PostMapping("/articles")
    @SaCheckRole("admin")
    public R addArticles(@RequestBody ArticleVo vo){
        articleService.saveOrUpdateArticle(vo);
        return R.ok();
    }

    /**
     * 文章列表查询
     * @param vo
     * @return
     */
    @GetMapping("/articles")
    public TableDataInfo<ArticleAdminDTO> ArticleList(ConditionVO vo, PageQuery pageQuery){
        TableDataInfo<ArticleAdminDTO> list =articleService.articleList(vo,pageQuery);
        return list;
    }


    /**
     * 修改文章是否置顶和推荐
     * @param articleTopFeaturedVO
     * @return
     */
    @PutMapping("/articles/topAndFeatured")
    @SaCheckRole("admin")
    public R topAndFeatured(ArticleTopFeaturedVO articleTopFeaturedVO){
        articleService.updateArticleTopAndFeatured(articleTopFeaturedVO);
        return R.ok();
    }


    /**
     * 获取需要修改的文章info
     * @param articleId
     * @return
     */
    @GetMapping("/articles/{articleId}")
    public R editArticle(@PathVariable Long articleId){
        ArticleVo vo =articleService.editArticle(articleId);
        return R.ok(vo);
    }

    /**
     * 逻辑or恢复删除文章
     * @return
     */
    @PutMapping("/articles")
    //@SaCheckRole("admin")
    public R delLogicalArticle(@RequestBody LogicalDelVO vo){
        articleService.delLogicalArticle(vo);
        return R.ok();
    }

    /**
     * 真实删除文章等信息
     * @param ids
     * @return
     */
    @DeleteMapping("/articles/delete")
    @SaCheckRole("admin")
    public R delArticles(@RequestBody List<Long> ids){
        articleService.delArticles(ids);
        return R.ok();
    }

    /**
     * 批量导出
     * @param ids
     * @return
     */
    @PostMapping("/articles/export")
    //@SaCheckRole("admin")
    public R articlesExport(@RequestBody List<Long> ids){
        List<String> url=articleService.articleExport(ids);
        return R.ok(url);
    }


    /**
     * 批量导出成zip（本地模式）
     * @param ids
     * @param response
     * @throws IOException
     */
    @GetMapping(value = "/articles/localExport" )
    //@SaCheckRole("admin")
    public void  localArticlesExport(String ids, HttpServletResponse response) throws IOException {
        List<Long> list = Convert.toList(Long.class, ids);
        byte[] bytes = articleService.localArticlesExport(list, response);
        genCode(response,bytes);
    }

    /**
     * 导入文件
     * @param file
     * @return
     */
    @PostMapping("/articles/import")
    //@SaCheckRole("admin")
    public R articlesImport(MultipartFile file,@RequestParam(required = false) String type){
        articleService.articlesImport(file,type);
        return R.ok();
    }

    /**
     * 列表获取
     * @param vo
     * @param pageQuery
     * @return
     */
    @GetMapping("/categories")
    public TableDataInfo<CategoryAdminDTO> listCategories(ConditionVO vo, PageQuery pageQuery){
        TableDataInfo<CategoryAdminDTO>  tableDataInfo= categoryService.listCategoriesAdmin(vo,pageQuery);
        return tableDataInfo;
    }

    /**
     *  保存分类或修改分类
     * @param categoryVO
     * @return
     */
    @PostMapping("/categories")
    public R addOrUpdateCategories(@RequestBody CategoryVO categoryVO){
        categoryService.saveOrUpdate(categoryVO);
        return R.ok();
    }

    /**
     * 删除分类
     * @param categoryIds
     * @return
     */
    @DeleteMapping("/categories")
    public R delCategories(@RequestBody List<Long> categoryIds){
        categoryService.deleteWithValidByIds(categoryIds,Boolean.TRUE);
        return R.ok();
    }

    /**
     * 标签列表
     *
     * @param vo
     * @param pageQuery
     * @return
     */
    @GetMapping("/tags")
    public TableDataInfo<TagAdminDTO> listTags(ConditionVO vo, PageQuery pageQuery){
        return  tagService.listTagsAdmin(vo,pageQuery);
    }


    /**
     * 添加或删除标签
     *
     * @param tagVO
     * @return
     */
    @PostMapping("/tags")
    @SaCheckRole("admin")
    public R addOrUpdateTags(@RequestBody TagVO tagVO){
        tagService.saveOrUpdate(tagVO);
        return R.ok();
    }

    /**
     * 删除标签
     * @param tagsIds
     * @return
     */
    @DeleteMapping("/tags")
    public R delTags(@RequestBody List<Long> tagsIds){
        tagService.deleteWithValidByIds(tagsIds,Boolean.TRUE);
        return R.ok();
    }


    /**
     * 获得接口资源列表
     * @param keywords
     * @return
     */
    @GetMapping("/resources")
    public R resources(@RequestParam(required = false)String keywords){
        List<ResourceDTO> list=resourceService.queryList(keywords);
        return R.ok(list);
    }

    /**
     * 增加或修改资源接口
     * @param resourceVO
     * @return
     */
    @PostMapping("/resources")
    @SaCheckRole("admin")
    public R addOrUpdateResources(@RequestBody ResourceVO resourceVO){
        resourceService.saveOrUpdateResource(resourceVO);
//        return R.ok(list);
        return R.ok();
    }

    /**
     * 手动导入swagger数据
     * @return
     */
    @GetMapping("/importResources")
    public R importSwagger(){
        resourceService.importSwagger();
        return R.ok();
    }

    /**
     * 获得用户列表
     * @param vo
     * @param pageQuery
     * @return
     */
    @GetMapping("/users")
    public TableDataInfo<UserAdminDTO> listUsers(ConditionVO vo, PageQuery pageQuery){
        return  userAuthService.listUsers(vo,pageQuery);
    }

    /**
     * 展示所有的权限列表
     * @return
     */
    @GetMapping("/users/role")
    public R listRoles(){
        List<UserRoleDTO> userRoleDTOS = userRoleService.queryRoles();
        return R.ok(userRoleDTOS);
    }

    /**
     * 修改用户的权限信息
     * @param vo
     * @return
     */
    @PutMapping("/users/role")
    @SaCheckRole("admin")
    public R updateUserRole(@RequestBody @Valid UserRoleVO vo){
        userRoleService.updateUserRole(vo);
        return R.ok();
    }

    /**
     * 设置用户禁用状态
     * @param userDisableVO
     * @return
     */
    @PutMapping("/users/disable")
    @SaCheckRole("admin")
    public R updateUserDisable(@Valid @RequestBody UserDisableVO userDisableVO){
        userRoleService.updateUserDisable(userDisableVO);
        return R.ok();
    }

    /**
     * 获取网站配置
     *
     * @return
     */
    @GetMapping("/website/config")
    public R websiteConfig(){
        WebsiteConfigDTO websiteConfigDTO=websiteConfigService.getWebsiteConfig();
        return R.ok(websiteConfigDTO);
    }

    /**
     * 修改网站配置
     *
     * @return
     */
    @PutMapping ("/website/config")
    public R updateWebsiteConfig(@Valid @RequestBody WebsiteConfigVO websiteConfigVO){
       websiteConfigService.updateWebsiteConfig(websiteConfigVO);
        return R.ok();
    }

    /**
     *上传网站图片&logo
     *
     * @return
     */
    @PostMapping("/config/images")
    public R uploadConfigImg(MultipartFile file){
        String fileUrl = uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.CONFIG.getPath());
        return R.ok(R.message,fileUrl);
    }

    /**
     * 获取网站大屏信息
     *
     * @return
     */
    @GetMapping("/info")
    public R getBlogBackInfo(){
        WebAdminInfoDTO webAdminInfoDTO =webInfoService.getWebAdminInfo();
        return R.ok(webAdminInfoDTO);
    }
    /**
     * 获取用户区域分布
     *
     * @return
     */
    @GetMapping("/users/area")
    @SaIgnore
    public R<List<UserAreaDTO>> listUserAreas(ConditionVO conditionVO) {
        return R.ok(userAuthService.listUserAreas(conditionVO));
    }

    /**
     * 同步文章信息到ES中
     * @return
     */
    @GetMapping("/articleToEs")
    public R updateToEs(){
        articlesSearchMapper.deleteIndex("myarticle");
        articleService.saveArticleToEs();
        return R.ok();
    }

    /**
     * 后台查看评论
     *
     * @param conditionVO
     * @param pageQuery
     * @return
     */
    @GetMapping("/comments")
    public TableDataInfo<CommentAdminDTO> listComments(ConditionVO conditionVO,PageQuery pageQuery){
        return commentService.listCommentsAdmin(conditionVO,pageQuery);
    }

    @DeleteMapping("/comments")
    public  R delComments(@RequestBody List<Long> ids){
        commentService.delCommentsByIds(ids);
        return R.ok();
    }


    /**
     * 审核评论
     * @param reviewVO
     * @return
     */
    @PutMapping("/comments/review")
    public R verifyComment(@Valid @RequestBody ReviewVO reviewVO){
        commentService.updateCommentsReview(reviewVO);
        return R.ok();
    }


    /**
     * 上传说说文图片
     * @param file
     * @return
     */
    @PostMapping("/talks/images")
    public R saveTalkImages(MultipartFile file){
        String fileUrl = uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.TALK.getPath());
        return R.ok(R.message,fileUrl);
    }


    /**
     * 新增或者修改说说
     * @param talkVO
     * @return
     */
    @PostMapping("/talks")
    public R saveOrUpdateTalks(@Valid @RequestBody TalkVO talkVO){
        talkService.saveOrUpdateTalk(talkVO);
        return R.ok();
    }

    /**
     * 获取说说列表
     *
     * @param conditionVO
     * @param pageQuery
     * @return
     */
    @GetMapping("/talks")
    public  TableDataInfo<TalkAdminDTO> listBackTalks(ConditionVO conditionVO,PageQuery pageQuery) {
        return talkService.listBackTalks(conditionVO,pageQuery);
    }

    /**
     * 获取说说详情
     *
     * @param talkId
     * @return
     */
    @GetMapping("/talks/{talkId}")
    public  R getBackTalkById(@PathVariable("talkId") Integer talkId) {
        return R.ok(talkService.getBackTalkById(talkId));
    }



    /**
     * 删除说说图片
     * @param fileName
     * @return
     */
    @PostMapping("/talks/delImages")
    @SaCheckRole("admin")
    public R deleteTalksImage(@RequestParam String fileName){
        String name = FileNameUtil.getName(fileName);
        uploadStrategyContext.executeDeleteStrategy(FilePathEnum.TALK.getPath()+name);
        return R.ok();
    }

    /**
     * 删除说说
     *
     * @param talkId
     * @return
     */
    @DeleteMapping("/talks")
    public R delTalks(@RequestBody Integer talkId){
        talkService.deleteTalkById(talkId);
        return R.ok();
    }


    /**
     * 获取图片列表
     *
     * @param conditionVO
     * @param pageQuery
     * @return
     */
    @GetMapping("/photos")
    public R photoList(ConditionVO conditionVO,PageQuery pageQuery){
        return R.ok(photoService.listPhotos(conditionVO,pageQuery));
    }

    /**
     * 修改照片信息
     * @param
     * @return
     */
    @PutMapping("/photos")
    public R updatePhoto(@Valid @RequestBody PhotoInfoVO photoInfoVO) {
        photoService.updatePhoto(photoInfoVO);
        return R.ok();
    }

    /**
     * 移动照片相册
     *
     * @param photoVO
     * @return
     */
    @PutMapping("photos/album")
    public R updatePhotosAlbum(@Valid @RequestBody PhotoVO photoVO) {
        photoService.updatePhotosAlbum(photoVO);
        return R.ok();
    }

    /**
     * 查询相册信息
     *
     * @return
     */
    @GetMapping("/photos/albums/{albumId}/info")
    public R<PhotoAlbumAdminDTO> photoAlbumInfo(@PathVariable Integer albumId){
        PhotoAlbumAdminDTO photoAlbumAdminDTO= photoAlbumService.getInfo(albumId);
        return R.ok(photoAlbumAdminDTO);
    }

    /**
     * 获取后台相册列表信息
     *
     * 获取所有的相册
     *
     * @return
     */
    @GetMapping("/photos/albums/info")
    public R<List<PhotoAlbumDTO>> listPhotoAlbumBackInfos() {
        return R.ok(photoAlbumService.listPhotoAlbumInfosAdmin());
    }

    /**
     * 查看后台相册列表
     * @param conditionVO
     * @return
     */
    @GetMapping("/photos/albums")
    public R listPhotoAlbumBacks(ConditionVO conditionVO) {
        return R.ok(photoAlbumService.listPhotoAlbumsAdmin(conditionVO));
    }


    /**
     * 相册上传封面
     *
     * @param file
     * @return
     */
    @PostMapping("/photos/albums/upload")
    public R uploadAlbumsPhotos(MultipartFile file){
        String  url= uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.PHOTO.getPath());
        return R.ok(R.message,url);
    }

    /**
     * 逻辑删除相册
     *
     * @return
     */
    @DeleteMapping("/photos/albums/{id}")
    public R DelAlbums(@PathVariable("id") Long id){
        photoAlbumService.deleteAlbums(id);
        return R.ok();
    }


    /**
     * 上传个人图片（相册里面的）
     *
     * @param photos
     * @return
     */
    @PostMapping("/photos/upload")
    public R uploadPhotos(@Valid PhotosVO photos){
        photoService.savePhotos(photos);
        return R.ok(R.message);
    }

    /**
     * 删除或者恢复相片
     *
     *  逻辑
     * @return
     */
    @PutMapping("/photos/delete")
    public R delPhotos(@Valid @RequestBody DeleteVO deleteVO){
        photoService.DeleteOrRecoverPhotos(deleteVO);
        return R.ok();
    }

    /**
     * 真实删除图片
     *
     *
     * @return
     */
    @DeleteMapping("/photos")
    public R deletePhotos(@RequestBody List<Long> photoIds){
        photoService.deletePhotos(photoIds);
        return R.ok();
    }


    /**
     * 保存或更新相册
     * @param photoAlbumVO
     * @return
     */
    @PostMapping("/photos/albums")
    public R saveOrUpdatePhotoAlbum(@Valid @RequestBody PhotoAlbumVO photoAlbumVO){
        photoAlbumService.saveOrUpdatePhotoAlbum(photoAlbumVO);
        return R.ok();
    }


    /**
     * 生成zip文件
     */
    private void genCode(HttpServletResponse response, byte[] data) throws IOException {
        response.reset();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=\"articles.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IoUtil.write(response.getOutputStream(), false, data);
    }




}
